package study.spring.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import study.spring.core.ioc._2_inject_bean.AtBeanAnnotationBean;
import study.spring.core.ioc._2_inject_bean.BeanConfig;
import study.spring.core.ioc._2_inject_bean.ComponentBean;
import study.spring.core.ioc._2_inject_bean.ComponentScanConfig;
import study.spring.core.ioc._2_inject_bean.JavaCodeConfigImportXmlResource;
import study.spring.core.ioc._2_inject_bean.XmlDefineBean;

public class SpringCore {

  /**
   * 主要看这里 {@link org.springframework.context.support.AbstractApplicationContext#refresh()}  }
   * <p>
   * spring bean 实例化的三种方式：就是 Java中三种创建对象的方式: new 操作符调用构造器(无参 或 含参);  static method (static factory method 静态方法); instance method (instance factory method) 实例工厂方法
   */
  public static void main(String[] args) {
    // 混合使用
    useJavaCodeConfigImportXmlResource();

    useJavaCodeAtBeanAnnotation(); //

    useXmlDefineBean(); //

  }

  /**
   * Java config的@Bean , spring xml(传统) 文件, 两种注入bean写法, 混合使用
   */
  static void useJavaCodeConfigImportXmlResource() {
    ApplicationContext context = new AnnotationConfigApplicationContext(JavaCodeConfigImportXmlResource.class);
    JavaCodeConfigImportXmlResource config = (JavaCodeConfigImportXmlResource) context.getBean("javaCodeConfigImportXmlResource");
    AtBeanAnnotationBean example = context.getBean(AtBeanAnnotationBean.class);
    String s = example.printSomeThing();
  }

  /**
   * 使用 JavaCode @Bean注解, 创建 BeanFactory
   */
  static void useJavaCodeAtBeanAnnotation() {
    ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
    // groovy 代码    创建 BeanFactory（略）

    AtBeanAnnotationBean example = context.getBean(AtBeanAnnotationBean.class);
    String s = example.printSomeThing();

  }

  /**
   * 使用xml文件    创建 beanFactory
   */
  static void useXmlDefineBean() {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

    XmlDefineBean xmlDefineBean = context.getBean("xmlDefineBean", XmlDefineBean.class);
    xmlDefineBean.describeSelf();
    // groovy 代码    创建 BeanFactory（略）
  }

  /**
   * 使用 @component-scan 与 @Component、@Repository、 @Service、@Controller 注解结合，创建 beanFactory
   */
  static void useComponentScanAnnotation() {
    ApplicationContext context = new AnnotationConfigApplicationContext(ComponentScanConfig.class);
    ComponentBean componentBean = context.getBean(ComponentBean.class);
    componentBean.describeSelf();
  }


}
